#include <stdio.h>
#include <stdlib.h>
#include "lda.h"

void lda(Imagem *img, Imagem **rotulo)
{
     ListaOrdenada *inicio;
     int comeco, n;
     
     comeco = 0;
     
     /* cria filas ordenadas para trabalhar nelas */
     inicio = (ListaOrdenada* )MontaListaOrdenada();
     
     /* inserindo nas filas o pixels basicos que jah foram etiquetados */
     IniciaFila(img, *rotulo, inicio, comeco);
     
     /* numero total de elementos da matriz para controlar qnd for percorrer */
     n = img->nlins * img->ncols;
     
     Inunda(*rotulo, inicio, n, img, 0);

	LiberaListaOrdenada(inicio);
	       
     return;
     
}

void Inunda(Imagem *rotulo, ListaSimples **inicio, int total,Imagem *img, int linhavet)
{
     int linha, coluna, posicao, prioridade,n,etq,indice;
	ListaSimples *atual;
  
	n = rotulo->ncols * rotulo->nlins;
     
     if(linhavet < 256)
     {
	  /* estando etiquetada, retira da fila e inunda seus vizinhos */
		if (inicio[linhavet]->prox == NULL)
		{
			LiberaListaSimples(&inicio[linhavet]);
			Inunda(rotulo, inicio, total, img, linhavet + 1);
		}
	  	else
	  	{
	       	/* DUVIDA DE QUAL TIRAR */
	       	atual = TiraElemento(inicio);
			etq = rotulo->val[atual->indice];
			indice = atual->indice;

			if (indice == 0)
			{
				linha = 0;
				coluna = 0;
			}
			else
			{
				linha = (indice)/(img->ncols);
				coluna = (indice)%(img->ncols);
			}
	       
			  /* inundar os vizinhos inserindo-os na lista ordenada */
			  
			  /* inserindo vizinho 1 */
			if (linha != 0)
			{
			  posicao = rotulo->lin[linha - 1] + coluna;
			  /*posicao = (rotulo)->ncols*(linha-1) + coluna -1;*/
			  prioridade = (img)->val[posicao];
				if (rotulo->val[posicao] == 0)
				{
					rotulo->val[posicao] = etq;
				  InsereListaOrdenada(inicio,prioridade,posicao, img);
				}
			  }
			  /* inserindo vizinho 2 */
			if (linha != 0 && coluna != img->ncols - 1)
			{
			posicao = rotulo->lin[linha - 1] + (coluna + 1);
	/*	       posicao = (rotulo)->ncols*(linha-1) + coluna;*/
			  prioridade = (img)->val[posicao];
			  if (rotulo->val[posicao] == 0)
				{
					rotulo->val[posicao] = etq;
				  InsereListaOrdenada(inicio,prioridade,posicao, img);
				}
			 } 
			  /* inserindo vizinho 3 */
			if (coluna != img->ncols - 1)
			{
			posicao = rotulo->lin[linha] + (coluna + 1);
	/*	       posicao = (rotulo)->ncols*(linha-1) + coluna +1;*/
			  prioridade = (img)->val[posicao];
			  if (rotulo->val[posicao] == 0)
				{
					rotulo->val[posicao] = etq;
				  InsereListaOrdenada(inicio,prioridade,posicao, img);
				}
			 } 
			  /* inserindo vizinho 4 */
			if (linha != img->nlins - 1 && coluna != img->ncols - 1)
			{
			posicao = rotulo->lin[linha + 1] + (coluna + 1);
		    /*   posicao = (rotulo)->ncols*(linha) + coluna -1;*/
			  prioridade = (img)->val[posicao];
			  if (rotulo->val[posicao] == 0)
				{
					rotulo->val[posicao] = etq;
				  InsereListaOrdenada(inicio,prioridade,posicao, img);
				}
			 } 
			  /* inserindo vizinho 5 */
			if (linha != img->nlins - 1)
			{
			posicao = rotulo->lin[linha + 1] + (coluna);
	/*	       posicao = (rotulo)->ncols*(linha-1) + coluna +1;*/
			  prioridade = (img)->val[posicao];
			  if (rotulo->val[posicao] == 0)
				{
					rotulo->val[posicao] = etq;
				  InsereListaOrdenada(inicio,prioridade,posicao, img);
				}
			 } 
			  /* inserindo vizinho 6 */
			if (linha != img->nlins - 1 && coluna != 0)
			{
			posicao = rotulo->lin[linha + 1] + (coluna - 1);
	/*	       posicao = (rotulo)->ncols*(linha+1) + coluna -1;*/
			  prioridade = (img)->val[posicao];
			  if (rotulo->val[posicao] == 0)
				{
					rotulo->val[posicao] = etq;
				  InsereListaOrdenada(inicio,prioridade,posicao, img);
				}
			 } 
			  /* inserindo vizinho 7 */
			if (coluna != 0)
			{
			posicao = rotulo->lin[linha] + (coluna - 1);
	/*	       posicao = (rotulo)->ncols*(linha+1) + coluna;*/
			  prioridade = (img)->val[posicao];
			  if (rotulo->val[posicao] == 0)
				{
					rotulo->val[posicao] = etq;
				  InsereListaOrdenada(inicio,prioridade,posicao, img);
				}
			 } 
			  /* inserindo vizinho 8 */
			if (linha != 0 && coluna != 0)
			{
			posicao = rotulo->lin[linha - 1] + (coluna - 1);
	/*	       posicao = (rotulo)->ncols*(linha+1) + coluna +1;*/
			  prioridade = (img)->val[posicao];
			  if (rotulo->val[posicao] == 0)
				{
					rotulo->val[posicao] = etq;
				  InsereListaOrdenada(inicio,prioridade,posicao, img);
				}
			}

/*  teste para ver se as posicoes certas estao sendo colocadas na lista nas prioridades certas */
		/*imprime(inicio);
		printf("\n");*/
	       
	       free(atual);

		Inunda(rotulo, inicio, total, img, linhavet);
	  }
     }
}
